import urllib.parse
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from typing import Optional, Dict, Any
import pyperclip
import webbrowser

class ShieldIOGenerator:
    """
    Shields.io URL 生成器
    支持静态徽章和动态徽章生成
    """
    
    # 预定义颜色常量
    COLORS = {
        'brightgreen': 'brightgreen',
        'green': 'green',
        'yellowgreen': 'yellowgreen',
        'yellow': 'yellow',
        'orange': 'orange',
        'red': 'red',
        'blue': 'blue',
        'lightgrey': 'lightgrey',
        'grey': 'grey',
        'success': 'brightgreen',
        'important': 'orange',
        'critical': 'red',
        'informational': 'blue'
    }
    
    # 预定义样式常量
    STYLES = {
        'flat': 'flat',
        'flat-square': 'flat-square',
        'plastic': 'plastic',
        'for-the-badge': 'for-the-badge',
        'social': 'social'
    }
    
    def __init__(self, base_url: str = "https://img.shields.io"):
        self.base_url = base_url.rstrip('/')
    
    def static_badge(self,
                    label: str,
                    message: str,
                    color: str = "blue",
                    label_color: Optional[str] = None,
                    style: str = "flat",
                    logo: Optional[str] = None,
                    logo_color: Optional[str] = None,
                    logo_size: Optional[str] = None,
                    logo_width: Optional[int] = None) -> str:
        """
        生成静态徽章 URL
        """
        # 处理空格和特殊字符
        label_encoded = self._encode_text(label)
        message_encoded = self._encode_text(message)
        
        # 构建基础URL
        url = f"{self.base_url}/badge/{label_encoded}-{message_encoded}-{color}"
        
        # 添加查询参数
        params = {}
        
        if label_color:
            params['labelColor'] = label_color
        if style and style != 'flat':
            params['style'] = style
        if logo:
            params['logo'] = logo
        if logo_color:
            params['logoColor'] = logo_color
        if logo_size:
            params['logoSize'] = logo_size
        if logo_width:
            params['logoWidth'] = str(logo_width)
        
        return self._add_query_params(url, params)
    
    def dynamic_json_badge(self,
                          url: str,
                          query: str,
                          label: str,
                          color: Optional[str] = None,
                          prefix: Optional[str] = None,
                          suffix: Optional[str] = None,
                          cache_seconds: Optional[int] = None,
                          default: Optional[str] = None,
                          style: str = "flat") -> str:
        """
        生成基于JSON API的动态徽章 URL
        """
        base_url = f"{self.base_url}/badge/dynamic/json"
        
        params = {
            'url': url,
            'query': query,
            'label': label
        }
        
        if color:
            params['color'] = color
        if prefix:
            params['prefix'] = prefix
        if suffix:
            params['suffix'] = suffix
        if cache_seconds is not None:
            params['cacheSeconds'] = str(cache_seconds)
        if default:
            params['default'] = default
        if style and style != 'flat':
            params['style'] = style
        
        return self._add_query_params(base_url, params)
    
    def dynamic_xml_badge(self,
                         url: str,
                         query: str,
                         label: str,
                         color: Optional[str] = None,
                         prefix: Optional[str] = None,
                         suffix: Optional[str] = None,
                         cache_seconds: Optional[int] = None) -> str:
        """
        生成基于XML的动态徽章 URL
        """
        base_url = f"{self.base_url}/badge/dynamic/xml"
        
        params = {
            'url': url,
            'query': query,
            'label': label
        }
        
        if color:
            params['color'] = color
        if prefix:
            params['prefix'] = prefix
        if suffix:
            params['suffix'] = suffix
        if cache_seconds is not None:
            params['cacheSeconds'] = str(cache_seconds)
        
        return self._add_query_params(base_url, params)
    
    def dynamic_yaml_badge(self,
                          url: str,
                          query: str,
                          label: str,
                          color: Optional[str] = None,
                          prefix: Optional[str] = None,
                          suffix: Optional[str] = None,
                          cache_seconds: Optional[int] = None) -> str:
        """
        生成基于YAML的动态徽章 URL
        """
        base_url = f"{self.base_url}/badge/dynamic/yaml"
        
        params = {
            'url': url,
            'query': query,
            'label': label
        }
        
        if color:
            params['color'] = color
        if prefix:
            params['prefix'] = prefix
        if suffix:
            params['suffix'] = suffix
        if cache_seconds is not None:
            params['cacheSeconds'] = str(cache_seconds)
        
        return self._add_query_params(base_url, params)
    
    def github_badge(self, badge_type: str, user: str, repo: str, **kwargs) -> str:
        """
        生成GitHub相关徽章
        """
        base_url = f"{self.base_url}/github"
        
        types = {
            'stars': f'stars/{user}/{repo}',
            'issues': f'issues/{user}/{repo}',
            'license': f'license/{user}/{repo}',
            'release': f'release/{user}/{repo}',
            'forks': f'forks/{user}/{repo}',
            'issues-pr': f'issues-pr/{user}/{repo}',
            'downloads': f'downloads/{user}/{repo}/total'
        }
        
        if badge_type not in types:
            raise ValueError(f"不支持的GitHub徽章类型: {badge_type}")
        
        url = f"{base_url}/{types[badge_type]}"
        
        if kwargs:
            url = self._add_query_params(url, kwargs)
        
        return url
    
    def npm_badge(self, package_name: str, badge_type: str = "version", **kwargs) -> str:
        """
        生成NPM相关徽章
        """
        base_url = f"{self.base_url}/npm"
        
        types = {
            'version': f'v/{package_name}',
            'downloads': f'dm/{package_name}',
            'types': f'types/{package_name}',
            'license': f'l/{package_name}'
        }
        
        if badge_type not in types:
            raise ValueError(f"不支持的NPM徽章类型: {badge_type}")
        
        url = f"{base_url}/{types[badge_type]}"
        
        if kwargs:
            url = self._add_query_params(url, kwargs)
        
        return url
    
    def _encode_text(self, text: str) -> str:
        """编码文本，处理空格和特殊字符"""
        encoded = text.replace(' ', '_')
        return urllib.parse.quote(encoded, safe='')
    
    def _add_query_params(self, url: str, params: Dict[str, str]) -> str:
        """添加查询参数到URL"""
        if not params:
            return url
        
        query_string = '&'.join([f"{k}={urllib.parse.quote(str(v))}" for k, v in params.items()])
        return f"{url}?{query_string}"


class ShieldIOGUI:
    """Shields.io URL 生成器 GUI 界面"""
    
    def __init__(self, root):
        self.root = root
        self.root.title("Shields.io URL 生成器")
        self.root.geometry("800x700")
        self.root.configure(bg='#f0f0f0')
        
        self.generator = ShieldIOGenerator()
        
        # 创建样式
        self.setup_styles()
        
        # 创建界面
        self.create_widgets()
        
    def setup_styles(self):
        """设置界面样式"""
        style = ttk.Style()
        style.configure('TFrame', background='#f0f0f0')
        style.configure('TLabel', background='#f0f0f0', font=('Arial', 10))
        style.configure('TButton', font=('Arial', 10))
        style.configure('Header.TLabel', font=('Arial', 12, 'bold'))
        
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题
        title_label = ttk.Label(main_frame, text="Shields.io URL 生成器", 
                               style='Header.TLabel')
        title_label.pack(pady=(0, 20))
        
        # 创建标签页
        notebook = ttk.Notebook(main_frame)
        notebook.pack(fill=tk.BOTH, expand=True)
        
        # 静态徽章标签页
        self.create_static_tab(notebook)
        
        # 动态徽章标签页
        self.create_dynamic_tab(notebook)
        
        # GitHub徽章标签页
        self.create_github_tab(notebook)
        
        # 结果展示区域
        self.create_result_section(main_frame)
        
        # 示例按钮
        example_frame = ttk.Frame(main_frame)
        example_frame.pack(fill=tk.X, pady=10)
        
        ttk.Button(example_frame, text="生成示例", 
                  command=self.generate_examples).pack(side=tk.LEFT, padx=5)
        
    def create_static_tab(self, notebook):
        """创建静态徽章标签页"""
        static_frame = ttk.Frame(notebook, padding="10")
        notebook.add(static_frame, text="静态徽章")
        
        # 基础信息
        ttk.Label(static_frame, text="标签:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.static_label = ttk.Entry(static_frame, width=30)
        self.static_label.grid(row=0, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(static_frame, text="消息:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.static_message = ttk.Entry(static_frame, width=30)
        self.static_message.grid(row=1, column=1, sticky=tk.W, pady=5)
        
        # 颜色选择
        ttk.Label(static_frame, text="颜色:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.static_color = ttk.Combobox(static_frame, values=list(self.generator.COLORS.keys()), width=27)
        self.static_color.set('blue')
        self.static_color.grid(row=2, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(static_frame, text="标签颜色:").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.static_label_color = ttk.Combobox(static_frame, values=list(self.generator.COLORS.keys()), width=27)
        self.static_label_color.grid(row=3, column=1, sticky=tk.W, pady=5)
        
        # 样式选择
        ttk.Label(static_frame, text="样式:").grid(row=4, column=0, sticky=tk.W, pady=5)
        self.static_style = ttk.Combobox(static_frame, values=list(self.generator.STYLES.keys()), width=27)
        self.static_style.set('flat')
        self.static_style.grid(row=4, column=1, sticky=tk.W, pady=5)
        
        # Logo设置
        ttk.Label(static_frame, text="Logo:").grid(row=5, column=0, sticky=tk.W, pady=5)
        self.static_logo = ttk.Entry(static_frame, width=30)
        self.static_logo.grid(row=5, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(static_frame, text="Logo颜色:").grid(row=6, column=0, sticky=tk.W, pady=5)
        self.static_logo_color = ttk.Entry(static_frame, width=30)
        self.static_logo_color.grid(row=6, column=1, sticky=tk.W, pady=5)
        
        # 生成按钮
        ttk.Button(static_frame, text="生成静态徽章", 
                  command=self.generate_static).grid(row=7, column=0, columnspan=2, pady=10)
        
    def create_dynamic_tab(self, notebook):
        """创建动态徽章标签页"""
        dynamic_frame = ttk.Frame(notebook, padding="10")
        notebook.add(dynamic_frame, text="动态徽章")
        
        # 数据类型选择
        ttk.Label(dynamic_frame, text="数据类型:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.data_type = ttk.Combobox(dynamic_frame, values=['json', 'xml', 'yaml'], width=27)
        self.data_type.set('json')
        self.data_type.grid(row=0, column=1, sticky=tk.W, pady=5)
        
        # API URL
        ttk.Label(dynamic_frame, text="API URL:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.dynamic_url = ttk.Entry(dynamic_frame, width=30)
        self.dynamic_url.grid(row=1, column=1, sticky=tk.W, pady=5)
        
        # 查询表达式
        ttk.Label(dynamic_frame, text="查询表达式:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.dynamic_query = ttk.Entry(dynamic_frame, width=30)
        self.dynamic_query.grid(row=2, column=1, sticky=tk.W, pady=5)
        
        # 标签
        ttk.Label(dynamic_frame, text="标签:").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.dynamic_label = ttk.Entry(dynamic_frame, width=30)
        self.dynamic_label.grid(row=3, column=1, sticky=tk.W, pady=5)
        
        # 其他参数
        ttk.Label(dynamic_frame, text="颜色:").grid(row=4, column=0, sticky=tk.W, pady=5)
        self.dynamic_color = ttk.Combobox(dynamic_frame, values=list(self.generator.COLORS.keys()), width=27)
        self.dynamic_color.grid(row=4, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(dynamic_frame, text="前缀:").grid(row=5, column=0, sticky=tk.W, pady=5)
        self.dynamic_prefix = ttk.Entry(dynamic_frame, width=30)
        self.dynamic_prefix.grid(row=5, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(dynamic_frame, text="后缀:").grid(row=6, column=0, sticky=tk.W, pady=5)
        self.dynamic_suffix = ttk.Entry(dynamic_frame, width=30)
        self.dynamic_suffix.grid(row=6, column=1, sticky=tk.W, pady=5)
        
        # 生成按钮
        ttk.Button(dynamic_frame, text="生成动态徽章", 
                  command=self.generate_dynamic).grid(row=7, column=0, columnspan=2, pady=10)
        
    def create_github_tab(self, notebook):
        """创建GitHub徽章标签页"""
        github_frame = ttk.Frame(notebook, padding="10")
        notebook.add(github_frame, text="GitHub徽章")
        
        # 用户和仓库
        ttk.Label(github_frame, text="用户名:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.github_user = ttk.Entry(github_frame, width=30)
        self.github_user.grid(row=0, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(github_frame, text="仓库名:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.github_repo = ttk.Entry(github_frame, width=30)
        self.github_repo.grid(row=1, column=1, sticky=tk.W, pady=5)
        
        # 徽章类型
        ttk.Label(github_frame, text="徽章类型:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.github_type = ttk.Combobox(github_frame, 
                                       values=['stars', 'issues', 'license', 'release', 'forks'], 
                                       width=27)
        self.github_type.set('stars')
        self.github_type.grid(row=2, column=1, sticky=tk.W, pady=5)
        
        # 生成按钮
        ttk.Button(github_frame, text="生成GitHub徽章", 
                  command=self.generate_github).grid(row=3, column=0, columnspan=2, pady=10)
        
    def create_result_section(self, parent):
        """创建结果展示区域"""
        result_frame = ttk.LabelFrame(parent, text="生成的URL", padding="10")
        result_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        
        # URL显示框
        self.url_text = scrolledtext.ScrolledText(result_frame, height=4, width=80)
        self.url_text.pack(fill=tk.BOTH, expand=True)
        
        # 按钮框架
        button_frame = ttk.Frame(result_frame)
        button_frame.pack(fill=tk.X, pady=5)
        
        ttk.Button(button_frame, text="复制URL", 
                  command=self.copy_url).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="预览徽章", 
                  command=self.preview_badge).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="清除", 
                  command=self.clear_result).pack(side=tk.LEFT, padx=5)
        
    def generate_static(self):
        """生成静态徽章"""
        try:
            label = self.static_label.get().strip()
            message = self.static_message.get().strip()
            
            if not label or not message:
                messagebox.showwarning("输入错误", "请填写标签和消息")
                return
                
            url = self.generator.static_badge(
                label=label,
                message=message,
                color=self.static_color.get(),
                label_color=self.static_label_color.get() or None,
                style=self.static_style.get(),
                logo=self.static_logo.get() or None,
                logo_color=self.static_logo_color.get() or None
            )
            
            self.display_result(url)
            
        except Exception as e:
            messagebox.showerror("生成错误", f"生成徽章时出错: {str(e)}")
    
    def generate_dynamic(self):
        """生成动态徽章"""
        try:
            data_type = self.data_type.get()
            api_url = self.dynamic_url.get().strip()
            query = self.dynamic_query.get().strip()
            label = self.dynamic_label.get().strip()
            
            if not all([api_url, query, label]):
                messagebox.showwarning("输入错误", "请填写API URL、查询表达式和标签")
                return
                
            if data_type == 'json':
                url = self.generator.dynamic_json_badge(
                    url=api_url,
                    query=query,
                    label=label,
                    color=self.dynamic_color.get() or None,
                    prefix=self.dynamic_prefix.get() or None,
                    suffix=self.dynamic_suffix.get() or None
                )
            elif data_type == 'xml':
                url = self.generator.dynamic_xml_badge(
                    url=api_url,
                    query=query,
                    label=label,
                    color=self.dynamic_color.get() or None,
                    prefix=self.dynamic_prefix.get() or None,
                    suffix=self.dynamic_suffix.get() or None
                )
            else:  # yaml
                url = self.generator.dynamic_yaml_badge(
                    url=api_url,
                    query=query,
                    label=label,
                    color=self.dynamic_color.get() or None,
                    prefix=self.dynamic_prefix.get() or None,
                    suffix=self.dynamic_suffix.get() or None
                )
            
            self.display_result(url)
            
        except Exception as e:
            messagebox.showerror("生成错误", f"生成动态徽章时出错: {str(e)}")
    
    def generate_github(self):
        """生成GitHub徽章"""
        try:
            user = self.github_user.get().strip()
            repo = self.github_repo.get().strip()
            badge_type = self.github_type.get()
            
            if not user or not repo:
                messagebox.showwarning("输入错误", "请填写GitHub用户名和仓库名")
                return
                
            url = self.generator.github_badge(badge_type, user, repo)
            self.display_result(url)
            
        except Exception as e:
            messagebox.showerror("生成错误", f"生成GitHub徽章时出错: {str(e)}")
    
    def generate_examples(self):
        """生成示例徽章"""
        examples = [
            "=== 静态徽章示例 ===",
            self.generator.static_badge("版本", "1.0.0", "brightgreen"),
            self.generator.static_badge("Python", "3.8", "blue", logo="python", logo_color="white"),
            "",
            "=== 动态徽章示例 ===",
            self.generator.dynamic_json_badge(
                url="https://api.github.com/repos/vuejs/vue",
                query="$.stargazers_count",
                label="Stars",
                color="gold",
                prefix="⭐"
            ),
            "",
            "=== GitHub徽章示例 ===",
            self.generator.github_badge("stars", "vuejs", "vue"),
            self.generator.github_badge("license", "vuejs", "vue")
        ]
        
        result_text = "\n".join(examples)
        self.display_result(result_text)
    
    def display_result(self, text):
        """显示结果"""
        self.url_text.delete(1.0, tk.END)
        self.url_text.insert(1.0, text)
    
    def copy_url(self):
        """复制URL到剪贴板"""
        text = self.url_text.get(1.0, tk.END).strip()
        if text:
            pyperclip.copy(text)
            messagebox.showinfo("成功", "URL已复制到剪贴板")
        else:
            messagebox.showwarning("警告", "没有可复制的内容")
    
    def preview_badge(self):
        """预览徽章"""
        text = self.url_text.get(1.0, tk.END).strip()
        if text and text.startswith('http'):
            webbrowser.open(text)
        else:
            messagebox.showwarning("警告", "没有有效的URL可预览")
    
    def clear_result(self):
        """清除结果"""
        self.url_text.delete(1.0, tk.END)


def main():
    """主函数"""
    try:
        import tkinter as tk
        from tkinter import ttk
    except ImportError:
        print("请安装 tkinter 来使用 GUI 界面")
        return
    
    root = tk.Tk()
    app = ShieldIOGUI(root)
    root.mainloop()


if __name__ == "__main__":
    main()